﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Example.MessagePipelines
{
    /// <summary>
    /// 消息异步管道构建器接口
    /// </summary>
    /// <typeparam name="MsgContext"></typeparam>
    public interface IMessageAsyncPipelineBuilder<MsgContext>
    {
        IMessageAsyncPipelineBuilder<MsgContext> Use(Func<Func<MsgContext, Task>, Func<MsgContext, Task>> middleware);

        Func<MsgContext, Task> Build();
    }

    /// <summary>
    /// 消息异步管道构建器实现
    /// </summary>
    /// <typeparam name="MsgContext"></typeparam>
    public class MessageAsyncPipelineBuilder<MsgContext> : IMessageAsyncPipelineBuilder<MsgContext>
    {
        private readonly Func<MsgContext, Task> _completeFunc;

        private readonly IList<Func<Func<MsgContext, Task>, Func<MsgContext, Task>>> _components;

        public MessageAsyncPipelineBuilder(Func<MsgContext, Task> completeFunc)
        {
            this._components = new List<Func<Func<MsgContext, Task>, Func<MsgContext, Task>>>();
            this._completeFunc = completeFunc;
        }

        public Func<MsgContext, Task> Build()
        {
            var request = this._completeFunc;

            //按照注入的顺序，遍历执行
            foreach (var component in this._components.Reverse())
            {
                request = component(request);
            }

            return request;
        }

        public IMessageAsyncPipelineBuilder<MsgContext> Use(Func<Func<MsgContext, Task>, Func<MsgContext, Task>> middleware)
        {
            this._components.Add(middleware);
            return this;
        }
    }
}
